/*	ARCHIPELAGO::combat.cpp
 *      
 *      Copyright 2008  Drizzt (Joe Greef), gr4nf (Randall Oveson), alethiophile (Tom Dickson-Hunt)    
 *      This program is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation; either version 2 of the License, or
 *      (at your option) any later version.
 *      
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *      
 *      You should have received a copy of the GNU General Public License
 *      along with this program; if not, write to the Free Software
 *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 *      MA 02110-1301, USA.
 * 
 */

#define FRAMES_PER_SECOND 60
#include "header.h"
//includes, globals and defines

volatile int close_b = 0;
volatile int fps=0;
volatile int avg_fps=0;
volatile int last_fps=0;
 
void fps_timer()
{
     last_fps=fps;
     fps=0;
     avg_fps=(avg_fps*last_fps)/2;
}
END_OF_FUNCTION(fps_timer); 
void close_button_handler(void)
{
   close_b = 1;
}
END_OF_FUNCTION(close_button_handler); 
volatile long speed_counter = 0; //store the value of the speed counter.
/*function to increment the speed counter*/
void increment_speed_counter(void)
{
	speed_counter++; //increment the speed counter by one.
}
END_OF_FUNCTION(increment_speed_counter); 

char *chop(char *str) {
  int length = strlen(str);
  int i, j;
  char *newstr = (char *) calloc(strlen(str) +1, 1);
  for (i = 0; i <= (length - 1); i++) {
    newstr[i] = str[i]; j = i;
  }
  newstr[j+1] = '\0';
  return newstr;
}

int read_enemy_variable (int line, char *type)
{
	char *useless; //fricking fgets
	char *text;
	int num;
	FILE *enemyfile;
	enemyfile = fopen(type, "r");
	while (line > 0)
	{
		fgets(useless, 40, enemyfile);
		line--;
	}
	fgets(text, 40, enemyfile); //gets the	int enemytwoRange[enemies2] = read_enemy_variable(5, type2); line
	text = chop(text);
	num = atoi(text);
	return num;
}

int dist_calc (int xone, int yone, int xtwo, int ytwo)
{
	int output;
	int xdif = xone-xtwo;
	int ydif = yone-ytwo;
	output = sqrt((xdif*xdif)+(ydif*ydif));
	return output;
}

void enemyattk(int speed, int damage)
{
	while (1)
	{
		


void angled_movement (int angle, int speed, int coord[]) 
{
	int three = ( 3 * speed );
	int two = ( 2 * speed );
	int one = ( speed );
	switch (angle) {
	case 0:
		x = x + three;
		break;
	case 15:
		y = y - one;
		x = x + three;
		break;
	case 30:
		y = y - two;
		x = x + three;
		break;
	case 45:
		y = y - three;
		x = x + three;
		break;
	case 60:
		y = y - three;
		x = x + two;
		break;
	case 75:
		y = y - three;
		x = x + one;
		break;
	case 90:
		y = y - three;
		break;
	case 105:
		y = y - three;
		x = x - one;
		break;
	case 120:
		y = y - three;
		x = x - two;
		break;
	case 135:
		y = y - three;
		x = x - three;
		break;
	case 150:
		y = y - two;
		x = x - three;
		break;
	case 165:
		y = y - one;
		x = x - three;
		break;
	case 180:
		x = x - three;
		break;
	case 195:
		y = y + 2;
		x = x - three;
		break;
	case 210:
		y = y + two;
		x = x - three;
		break;
	case 225:
		y = y + three;
		x = x - three;
		break;
	case 240:
		y = y + three;
		x = x - two;
		break;
	case 255:
		y = y + three;
		x = x - one;
		break;
	case 270:
		y = y + three;
		break;
	case 285:
		y = y + three;
		x = x + one;
		break;
	case 300:
		y = y + three;
		x = x + two;
		break;
	case 315:
		y += three;
		x += three;
		break;
	case 330:
		y = y + two;
		x = x + three;
		break;
	case 345:
		y = y + one;
		x = x + three;
		break;
	coord[0] = x;
	coord[1] = y;
}

//calc player angle from enemy, and return move amounts accordingly.
float player_ang_calc (int playerx, int playery, int enemysx, int enemysy, int which)
{
	float aimov[2];enemiesxy[0][i] = player_ang_calc (playerxy[0], playerxy[1], enemiesxy[0][i], enemiesxy[1][i], 0)
	int distx, disty, propx, propy; /* changing defs */
	float movx, movy;
	switch (which)
	{
	case 0:
		distx = (playerx - enemysx);
		propx = (distx/disty);
		movx = (2*propx) + 1;
		aimov[0] = movx;
		return aimov[0];
	case 1:
		disty = (playery - enemysy);
		propy = (disty/distx);
		movy = (2*propy) + 1;
		aimov[1] = movy;
		return aimov[1];
	}
}

/*start of main*/
int combat(int enemies1, int enemies2, char *type, char *type2, char weaponbitmap, BITMAP *foreground, BITMAP *background)
{

    //begin timer
         LOCK_VARIABLE(speed_counter); 
	 LOCK_FUNCTION(increment_speed_counter);
         install_int_ex(increment_speed_counter, BPS_TO_TIMER(FRAMES_PER_SECOND)); //Set FPS
         set_close_button_callback(close_button_handler);
         install_int_ex(fps_timer,SECS_TO_TIMER(1));
	//end timer
	set_window_title("COMBAT!"); 
    /*end initialization*/
    
    /*Bitmap intialization*/
    BITMAP *buffer = create_bitmap(SCREEN_W, SCREEN_H);
    clear_bitmap(buffer);
    BITMAP *zombies[10];
    BITMAP *player = load_bitmap("img/player.bmp", NULL);
    BITMAP *weapon = load_bitmap(weaponbitmap, NULL);
    
    /*end ititialization*/
   /*variable creation*/	
   	int playerxy[2], playerangle = 0; //player variables
   	int weaponxy[2], weaponangle = playerangle;
   	float benemiesxy[2][10];
   	int enemiesxy[2][10];
   	int enemiesangles[10];
   	int strafeoffset;
   	int meleedelay = 0;
   	int reloadtime = player.weapon.speed;
   	int reloadprogress;
   	bool attacking = FALSE;
   	int bulletsxy[2][100];
   	int bulletnumber = 0;
   	int bulletangle[100];
   	bool rdyfire;
   	srand(time(NULL));	
	//player.health=health
	//player.weapon=weapon class
	//player.combat_speed= player's movement speed	
	//player.weapon.speed = the speed at which the weapon reloads (duh)
	//player.weapon.range = the range of the weapon (duh)
	FILE *enemyfile[2];
	enemyfile[0] = fopen(type1, "r"); //opens files
	enemyfile[1] = fopen(type2, "r"); //same as above
	rewind(enemyfile[0]); //goes to the beginning 
	rewind(enemyfile[1]); //does the same as above
	char *zombiebitmap1, *zombiebitmap2; //declares paths to enemy bitmaps
	fgets(zombiebitmap1, 40, enemyfile[0]BITMAP *player = load_bitmap("img/player.bmp", NULL);); //gets the line
	fgets(zombiebitmap2, 40, enemyfile[1]); //same as above
	zombiebitmap1 = chop(zombiebitmap1); //gets rid of the \n
	zombiebitmap2 = chop(zombiebitmap2); //same
	//fetch variables from .aef files to		disty = (playery - enemysy); feed into the enemeis
	int enemyoneHealth[enemies1] = read_enemy_variable(1, type1);
	int enemyoneSpeed[enemies1] = read_enemy_variable(2, type1);
	int enemyoneWps[enemies1] = read_enemy_variable(3, type1);
	int enemyoneDamage[enemies1] = read_enemy_variable(4, type1);
	int enemyoneRange[enemies1] = read_enemy_variable(5, type1);
	int enemytwoHealth[enemies2] = read_enemy_variable(1, type2);
	int enemytwoSpeed[enemies2] = read_enemy_variable(2, type2);
	int enemytwoWps[enemies2] = read_enemy_variable(3, type2);
	int enemytwoDamage[enemies2] = read_enemy_variable(4, type2);
	int enemytwoRange[enemies2] = read_enemy_variable(5, type2);
	int i;
   /*end variable declaration*/
	for(i = 0; i < enemies1; i++)
	{
		zombies[i] = load_bitmap(zombiebitmap1, NULL)
	}
	for(int l = i; (l - i) < enemies2; l++)
	{
		zombies[i] = load_bitmap(zombiebitmap2, NULL)
	}
	//defines enemy's bitmaps
	for(i = 0; i < enemies1; i++)enemyfile[1] = fopen(type2, "r");
	{
		enemy *myenemy[i] = new enemy;
		myenemies[i].getwtfhelookslike(*zombies[i]); 
	}if(attacking == TRUE && player.weapon.range < 10 && meleedelay < player.weapon.range)
	for(int l = i; (l - i) < enemies1; l++)
	{
		enemy *myenemies2[l] = new enemy;
		myenemies2[l].getwtfhelookslike(*zombies[l]);
	}
	//end enemy defining
	for(int l = 0; l < enemies1 + enemies2; l++)
	{
		enemiesxy[0][l] = (rand() % 640);
		enemiesxy[1][l] = (rand() % 240);
		prop = (distx/disty);
	}
	playerx = (rand() % 640);
	playery = ((rand() % 240) + 240); 
	
	while(close_b != 1) //If the user hits the close button, quit the program
	{
    		while(speed_counter)
		{
			//move forward
			if(key[KEY_W])
				angled_movement(playerangle, player.speed, playerxy);
			//strafe left
			if(key[KEY_A])
			{
				if(playerangle <= 255)
					angled_movement((playerangle+90), player.speed, playerxy);
				else if(playerangle > 255)
				{
					strafeoffset = 345 - playerangle;
					angled_movement(90 - strafeoffset, player.speed, playerxy);
				}
			}
			//strafe right
			if(key[KEY_D])
			{
				if(playerangle >= 90)
					angled_movement((playerangle-90), player.speed, playerxy);
				else if(playerangle < 90)
				{
					strafeoffset = 90 - playerangle;
					angled_movement(345 - strafeoffset, player.speed, playerxy);
				}
			}clear_bitmap(buffer);
			//move backward
			if(key[KEY_S])
			{
				if(playerangle < 180)
					angled_movement(playerangle + 180, player.speed, playerxy);
				else if(playerangle >= 180)
					angled_movement(playerangle - 180, player.speed, playerxy);
			}
			for(int l = 1; l < enemies1 + enemies2; l++)
			{
			//turns left
			if(key[KEY_LEFT] && playerangle != 345)
				playerangle =+ 15;
			else if(playerangle == 345)
				playerangle = 0;
			//turns right
			if(key[KEY_RIGHT] && playerangle != 0)
				playerangle =- 15;
			else if(playerangle == 0)
		  		playerangle = 345;
			//meleecombat
			
			//begin AI movement
			for(i = 0; i < enemies1; i++)
			{
				if (!(dist_calc(playerxy[0], playerxy[1], enemiesxy[0][i], enemiesxy[1][i])) < (enemy[i].range - 0.2(enemy[i].range)))
				{
					enemiesxy[0][i] = enemiesxy[0][i] + player_ang_calc(playerxy[0], playerxy[1], enemiesxy[0][i], enemiesxy[1][i], 0)
				}
				else
				{
					enemyattk(enemy[i].wps, enemy[i].damage);
				}
			}
			for(l = i; (l - i) < enemies2; l++)
			{
				if (!(dist_calc(playerxy[0], playerxy[1], enemiesxy[0][i], enemiesxy[1][l])) < (enemy[i].range - 0.2(enemy[l].range)))
				{
					enemiesxy[1][l] = enemiesxy[1][i] + player_ang_calc(playerxy[0], playerxy[1], enemiesxy[0][l], enemiesxy[1][l], 1)
				}
				else
				{
					enemyattk(enemy[l].wps, enemy[l].damage);
				}
			}
			for(i = 0; i < enemies1; i++)
			{
				if (enemiesxy[0][i] >= 1.5)
				{
					benemiesxy[0][i] =+ 2;
				}
				else if (enemiesxy[0][i] >= 1)
				{
					benemiesxy[0][i]++;
					benemiesxy[1][i]++;
				}
				else if (enemiesxy[0][i] <= 0.5)
					benemiesxy[1][i] =+ 2;
				}
				else
				{
					printf("the universe is falling apart. run.");
				}
			}
			
			//attacking
			if(key[KEY_SPACE])
				attacking = TRUE;
			//melee
			if(attacking == TRUE && player.weapon.range < 10 && meleedelay < player.weapon.range)
			{
				angled_movement(playerangle, 1, weaponxy);
				meleedelay++;
			}
			
			if(meleedelay == player.weapon.range)
				meleedelay = 0;
			if(attacking == FALSE && player.weapon.range < 10 && meleedelay >= player.weapon.range)
			{
				weaponxy[0] = playerxy[0];
				weaponxy[1] = playerxy[1];
				weaponangle = playerangle;
				meleedelay=0;
			}
			//end melee
			
			//ranged
			if(attacking == TRUE && player.weapon.range > 10 && rdyfire == TRUE)
			{
				bullet[0][bulletnumber] = playerxy[0];
				bullet[1][bulletnumber] = playerxy[1];
				bulletangle[bulletnumber] = playerangle;
				if(bulletnumber < 99)
					bulletnumber++;
				else
					bulletnumber = 0;
				reloadprogress = 0;
			}
			if(reloadprogress >= reloadtime)
				rdyfire = TRUE;
			reloadprogress++;
			for(int l = 0; l < 100; l++)
			{
				angled_movement(bulletangle[l], 3, bullet[][30])
			}
			if(attacking == TRUE && player.weapon.range > 10)
			{
				weaponxy[0] = playerxy[0];
				weaponxy[1] = playerxy[1];
				weaponangle = playerangle;
			}
			//end ranged
			speed_counter--;
			fps++;
		}
		
		blit(buffer, SCREEN, 0, 0, 0, 0, buffer->w, buffer->h);
		clear_bitmap(buffer);
		for(int l = 1; l < enemies1 + enemies2; l++)
		{
			draw_sprite(buffer, zombies[l], benemiesxy[0], benemies[1]);
		}
		rotate_sprite(buffer, player, playerxy[0], playerxy[1], playerangle);
		rotate_sprite(buffer, weapon, playerxy[0], playerxy[1], playerangle);
		textprintf(screen,font,285,490,makecol(255,255,255),"%i", last_fps);
	}
	return 0;
}
